package com.zengqingfa.springboot.redis.helper;


import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 根据ID生成
 * 默认6个数字,APP20190111000001这样子
 */
@Component
public class RedisIdentityHelper {

    /**
     * 应用名称
     */
    private static final String AUTH_PLATFORM_SERVICE = "MCSP_STOCK_SERVICE";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYYMMdd");

    /**
     * 201903220001
     * 201903220002
     * 201903230001
     * 根据前缀生成
     *
     * @param prefix 前缀
     * @return
     */
    public String getCommonCode(String prefix) {
        return getCode(prefix, AUTH_PLATFORM_SERVICE);
    }


    /**
     * @param prefix 前缀
     * @param redisKey rediskey
     * @return
     */
    public String getCode(String prefix, String redisKey) {
        return getCode(prefix, redisKey, 6);
    }

    /**
     * @param prefix 前缀
     * @param size 递增的数字长度
     * @return
     */
    public String getCommonCode(String prefix, int size) {
        return getCode(prefix, AUTH_PLATFORM_SERVICE, size);
    }

    /**
     * @param prefix
     * @param redisKey
     * @param size
     * @return
     */
    public String getCode(String prefix, String redisKey, int size) {
        return prefix + LocalDate.now().format(formatter) + StringUtils.leftPad(Integer.toString(generateOrderNum(redisKey)), size, '0');
    }


    /**
     * @param redisKey 这个key根据实际需要是否一个应用共用一个key还是一个业务一个key
     *                 如果一个业务一个key,则redisKey需要拼接一个前缀prefix
     * @return
     */
    public int generateOrderNum(String redisKey) {
        RedisAtomicInteger counter = new RedisAtomicInteger(redisKey, stringRedisTemplate.getConnectionFactory());
        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(23, 59, 59, 999_999_999);
        Duration duration = Duration.between(now, time);
        counter.expire(duration.getSeconds(), TimeUnit.SECONDS);
        return counter.incrementAndGet();
    }
}
